package com.tea.app.moudles.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tea.app.moudles.mapper.GoodsMapper;
import com.tea.common.entity.app.Goods;
import com.tea.common.entity.app.dto.GoodsDTO;
import com.tea.common.entity.app.vo.GoodsMenuVO;
import com.tea.common.mapper.GoodsStoreMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tea.app.moudles.mapper.GoodsCategoryMapper;

import com.tea.app.moudles.mapper.GoodsPropertyMapper;

import com.tea.common.common.enums.GoodsPropertyCategory;

import com.tea.common.entity.app.GoodsCategory;
import com.tea.common.entity.app.GoodsProperty;

import com.tea.common.entity.app.vo.GoodsVO;
import com.tea.common.entity.app.vo.SameCategoryPropertyVO;

import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.stream.Collectors;


import com.tea.common.entity.GoodsStore;

/**
 * 商品服务实现类
 */
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> {

    @Resource
    private GoodsCategoryMapper goodsCategoryMapper;
    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    private GoodsPropertyMapper goodsPropertyMapper;
    @Resource
    private GoodsStoreMapper goodsStoreMapper;

    /**
     * 获取商品菜单的详细列表
     *
     * @param storeId 门店ID
     * @return 包含商品菜单详细信息的列表
     */
    public List<GoodsMenuVO> getGoodsMenuDetailList(Long storeId) {
        // 从数据库中查询所有商品分类，返回商品分类列表
        List<GoodsCategory> goodsCategoryList = goodsCategoryMapper.selectList(null);
        // 使用2个map去关联关系，初始化一个用于存储同一分类下商品列表的map
        HashMap<String, List<Goods>> sameCategoryGoodsMap = new HashMap<>(goodsCategoryList.size());
        // 初始化一个用于存储商品菜单视图对象的map
        HashMap<String, GoodsMenuVO> goodsMenuVOMap = new HashMap<>(goodsCategoryList.size());
        // 遍历商品分类列表，为每个分类初始化数据
        for (GoodsCategory goodsCategory : goodsCategoryList) {
            // 将分类名称作为键，初始化一个空的商品列表作为值，存入 sameCategoryGoodsMap
            sameCategoryGoodsMap.put(goodsCategory.getName(), new ArrayList<>());
            // 创建一个新的商品菜单视图对象
            GoodsMenuVO goodsMenuVO = new GoodsMenuVO();
            goodsMenuVO.setGoodsCategoryName(goodsCategory.getName());
            goodsMenuVO.setGoodsCategoryName(goodsCategory.getName());
            goodsMenuVO.setDisplayOrder(goodsCategory.getDisplayOrder());
            goodsMenuVO.setGoodsCategoryShow(goodsCategory.getShowStatus());
            // 将分类名称作为键，商品菜单视图对象作为值，存入 goodsMenuVOMap
            goodsMenuVOMap.put(goodsCategory.getName(), goodsMenuVO);
        }
        
        // 查询该门店关联的所有商品ID
        List<Long> storeGoodsIds = new ArrayList<>();
        if (storeId != null) {
            // 查询门店上架的所有商品关联
            QueryWrapper<GoodsStore> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("store_id", storeId)
                       .eq("status", 1); // 状态为上架的商品
            List<GoodsStore> goodsStoreList = goodsStoreMapper.selectList(queryWrapper);
            
            // 提取所有商品ID
            storeGoodsIds = goodsStoreList.stream()
                                        .map(GoodsStore::getGoodsId)
                                        .collect(Collectors.toList());
            
            if (storeGoodsIds.isEmpty()) {
                // 如果该门店没有关联商品，直接返回空列表
                return new ArrayList<>();
            }
        }
        
        // 构建商品查询条件
        QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();
        // 如果有门店ID筛选，则添加条件
        if (storeId != null) {
            goodsQueryWrapper.in("id", storeGoodsIds);
        }
        
        // 从数据库中查询商品列表
        List<Goods> allGoods = goodsMapper.selectList(goodsQueryWrapper);
        
        // 将所有商品分类，除了"爆款推荐"分类
        for (Goods good : allGoods) {
            // 检查 sameCategoryGoodsMap 中是否包含该商品的分类名称
            if (sameCategoryGoodsMap.containsKey(good.getGoodsCategoryName())) {
                // 如果商品分类名称不是"爆款推荐"，则将该商品添加到对应分类的商品列表中
                if (!good.getGoodsCategoryName().equals("爆款推荐")) {
                    sameCategoryGoodsMap.get(good.getGoodsCategoryName()).add(good);
                }
            }
        }
        
        // 将所有推荐商品添加到"爆款推荐"分类中
        for (Goods good : allGoods) {
            // 检查商品是否为推荐商品
            if (good.getIsRecommend() && sameCategoryGoodsMap.containsKey("爆款推荐")) {
                // 将推荐商品添加到"爆款推荐"分类对应的商品列表中
                sameCategoryGoodsMap.get("爆款推荐").add(good);
            }
        }
        
        // 创建一个随机数生成器
        Random random = new Random(10000);
        // 关联同类商品排好序后放到到对应的类别里
        // 遍历 goodsMenuVOMap 中的每个条目
        for (Map.Entry<String, GoodsMenuVO> goodsMenuVOEntry : goodsMenuVOMap.entrySet()) {
            List<Goods> sameCategoryGoodsList = sameCategoryGoodsMap.get(goodsMenuVOEntry.getKey());
            // 对当前分类下的商品列表按照显示顺序进行排序
            sameCategoryGoodsList.sort(Comparator.comparingInt(Goods::getDisplayOrder));
            // 用于存储当前分类下转换后的商品视图对象列表
            List<GoodsVO> goodsVos = new ArrayList<>();

            // 填充商品的属性
            // 遍历当前分类下的每个商品
            for (Goods goods : sameCategoryGoodsList) {
                // 根据商品ID从数据库中查询该商品的所有属性
                List<GoodsProperty> goodsPropertyList = goodsPropertyMapper.selectList(
                        new QueryWrapper<GoodsProperty>().eq("goods_id", goods.getId()));
                // 用于存储商品属性按类别分组的映射
                HashMap<String, List<GoodsProperty>> propertyMap = new HashMap<>();
                // 遍历商品的属性列表
                for (GoodsProperty goodsProperty : goodsPropertyList) {
                    // 判断属性映射中是否已经存在该属性的类别
                    if (propertyMap.containsKey(goodsProperty.getCategory())) {
                        // 若存在，将该属性添加到对应类别的属性列表中
                        propertyMap.get(goodsProperty.getCategory()).add(goodsProperty);
                    } else {
                        // 若不存在，创建一个新的属性列表并添加该属性，然后放入属性映射中
                        propertyMap.put(goodsProperty.getCategory(), new ArrayList<GoodsProperty>() {{
                            add(goodsProperty);
                        }});
                    }
                    // 判断属性是否为默认属性，且属性类别是否为 ENUM_size
                    if (goodsProperty.getIsDefault() && GoodsPropertyCategory.ENUM_size.value.equals(goodsProperty.getCategory())) {
                        // 若是，则重新设置商品的默认价格
                        goods.setDefaultPrice(goodsProperty.getRebasePrice());
                    }
                }
                // 用于存储转换后的商品属性视图对象列表
                List<SameCategoryPropertyVO> goodsPropertyVos = new ArrayList<>();
                // 遍历属性映射中的每个条目
                for (Map.Entry<String, List<GoodsProperty>> entry : propertyMap.entrySet()) {
                    // 属性类别->属性列表  转换成对象
                    // 创建一个新的商品属性视图对象
                    SameCategoryPropertyVO goodsPropertyVo = new SameCategoryPropertyVO();
                    goodsPropertyVo.setCategory(entry.getKey());
                    goodsPropertyVo.setRequired(!GoodsPropertyCategory.ENUM_jia_liao.value.equalsIgnoreCase(entry.getKey())); // 除了加料其他全部必选
                    goodsPropertyVo.setPropertyList(entry.getValue());
                    // 将商品属性视图对象添加到列表中
                    goodsPropertyVos.add(goodsPropertyVo);
                }
                // 创建一个新的商品视图对象
                GoodsVO goodsVo = new GoodsVO();
                // 将商品对象的属性复制到商品视图对象中
                BeanUtils.copyProperties(goods, goodsVo);
                goodsVo.setGoodsPropertyVos(goodsPropertyVos);
                goodsVo.setRealPrice(goods.getDefaultPrice());
                // 动态刷新小程序里的图片，在图片URL后添加随机数
                goodsVo.setImage(goodsVo.getImage() + "?random=" + random.nextInt()); // 动态刷新小程序里的图片
                goodsVos.add(goodsVo);
            }
            // 将当前分类下的商品视图对象列表设置到对应的商品菜单视图对象中
            goodsMenuVOEntry.getValue().setGoodsList(goodsVos);
        }

        // 将 goodsMenuVOMap 中的所有商品菜单视图对象提取到一个列表中
        List<GoodsMenuVO> goodsMenuVOList = new ArrayList<>(goodsMenuVOMap.values());
        // 最后对菜单进行排序
        goodsMenuVOList.sort(Comparator.comparingInt(GoodsMenuVO::getDisplayOrder));
        return goodsMenuVOList;
    }

    public List<Goods> getAllGoods() {
        List<Goods> goodsDTOS = goodsMapper.selectList(null);
        //去除重复的商品名
        // 去除重复的商品名
        return goodsDTOS.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toMap(
                                Goods::getName,
                                goodsDTO -> goodsDTO,
                                (existing, replacement) -> existing // 保留第一个出现的商品
                        ),
                        map -> new ArrayList<>(map.values())
                ));
    }
}

